﻿using System.Collections;
using System.Collections.Generic;
using SharePhone.Common.Web;
using SharePhone.Core;
using SharePhone.Provider;

namespace SharePhone.Common.List
{
    public delegate void SPListLoadCompleted(object sender, SPListLoadCompletedEventArgs e);

    public class SPListCollection : IEnumerable
    {
        #region Variables

        private Dictionary<string, object> ListCache;

        #endregion

        #region Properties

        private SPWeb ParentWeb { get; set; }

        #endregion

        #region Constructors

        public SPListCollection(SPWeb parent)
        {
            ListCache = new Dictionary<string, object>();
            ParentWeb = parent;
        }

        #endregion

        #region Methods

        public void GetListByName<T>(string name, ListTransferCompleted<T> callback) where T : BaseItem, new()
        {
            GetListByName(name, callback, false);
        }

        public void GetListByName<T>(string name, ListTransferCompleted<T> callback, bool force)
            where T : BaseItem, new()
        {
            SPList<T> list = null;
            if (ListCache.ContainsKey(name) && !force)
            {
                list = (SPList<T>) ListCache[name];
                if (list.GetCacheStatus(ParentWeb.Settings) != CacheStatus.Old)
                {
                    list.ParentWeb = ParentWeb;
                    callback(list);
                }
                else
                {
                    GetListFromSharePoint(name, callback);
                }
            }
            else
            {
                GetListFromSharePoint(name, callback);
            }
        }

        public void LoadAll()
        {
            ListProvider.GetListCollection(ParentWeb, GetListCollection, ParentWeb.Settings.Credentials);
        }

        private void GetListFromSharePoint<T>(string name, ListTransferCompleted<T> callback) where T : BaseItem, new()
        {
            ListProvider.GetList(name, ParentWeb.Url, (SPList<T> list) =>
                                                          {
                                                              UpdateCache(list);
                                                              callback(list);
                                                          }, ParentWeb.Settings.Credentials);
        }

        private void UpdateCache<T>(SPList<T> list) where T : BaseItem, new()
        {
            list.ParentWeb = ParentWeb;
            if (ListCache.ContainsKey(list.Title))
                ListCache[list.Title] = list;
            else
                ListCache.Add(list.Title, list);
        }

        #endregion

        #region Callbacks

        private void GetListCollection(List<SPList<BaseItem>> lists)
        {
            ListCache = new Dictionary<string, object>();
            foreach (var list in lists)
                ListCache.Add(list.Title, list);
            FireLoadCompleted(lists);
        }

        #endregion

        #region Eventhandler

        public event SPListLoadCompleted LoadCompleted;

        private void FireLoadCompleted(List<SPList<BaseItem>> listsLoaded)
        {
            if (LoadCompleted != null)
                LoadCompleted(this, new SPListLoadCompletedEventArgs {Lists = listsLoaded});
        }

        #endregion

        #region IEnumerable Members

        public IEnumerator GetEnumerator()
        {
            return ListCache.Values.GetEnumerator();
        }

        #endregion
    }
}